package com.hcc.flow.server.controller.sys;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.hcc.flow.server.annotation.LogAnnotation;
import com.hcc.flow.server.common.constant.Constant;
import com.hcc.flow.server.common.model.ApiResult;
import com.hcc.flow.server.common.utils.CommUtil;
import com.hcc.flow.server.common.utils.StringUtilsV2;
import com.hcc.flow.server.dao.sys.PermissionDao;
import com.hcc.flow.server.dao.sys.RoleDao;
import com.hcc.flow.server.filter.TokenFilter;
import com.hcc.flow.server.model.common.LoginUser;
import com.hcc.flow.server.model.sys.Permission;
import com.hcc.flow.server.service.sys.PermissionService;
import com.hcc.flow.server.utils.UserUtil;
import com.hcc.flow.server.vo.sys.PermissionChildVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 菜单管理相关接口
 * 
 * @author 韩长长 
 *
 */
@Api(tags = "菜单管理")
@RestController
@RequestMapping("/permissions")
public class PermissionController {

	@Autowired
	private PermissionDao permissionDao;
	@Autowired
	private PermissionService permissionService;
	@Autowired
	private RoleDao roleDao;

	@ApiOperation(value = "权限（菜单）-当前登录用户拥有的权限")
	@GetMapping("/current")
	public List<PermissionChildVO> permissionsCurrent() {
		LoginUser loginUser = UserUtil.getLoginUser();
		/*List<Permission> list = loginUser.getPermissions();
		final List<Permission> permissions = list.stream().filter(l -> l.getType().equals(1)).collect(Collectors.toList());
		setChild(permissions);
		return permissions.stream().filter(p -> p.getParentId().equals("0")).collect(Collectors.toList());*/
		List<PermissionChildVO> list;
		if(Constant.SYSTEM_MANAGE_TOP_USER_IDS.contains(loginUser.getUserId())){
			list = permissionDao.listCAll(null,null);
		}else {
			list = permissionDao.listCAllByUserId(loginUser.getUserId(),null,null);
		}
		final List<PermissionChildVO> permissions = list.stream().filter(l -> (l.getType()<3)).collect(Collectors.toList());
		setChildNew(permissions); 
		return permissions.stream().filter(p -> p.getParentId().equals("0")).collect(Collectors.toList());
	}
	
	@ApiOperation(value = "权限（菜单）-当前登录用户拥有的权限")
	@GetMapping("/currentNew")
	public ApiResult<?> permissionsCurrentNew(HttpServletRequest request) {
		Integer sysid = TokenFilter.getSysId(request);
		LoginUser loginUser = UserUtil.getLoginUser();
		List<PermissionChildVO> list;
		if(Constant.SYSTEM_MANAGE_TOP_USER_IDS.contains(loginUser.getUserId())){
			list = permissionDao.listCAll(sysid,"50");
		}else {
			list = permissionDao.listCAllByUserId(loginUser.getUserId(),sysid,"50");
		}
		final List<PermissionChildVO> permissions = list.stream().filter(l -> (l.getType()<3)).collect(Collectors.toList());
		setChildNew(permissions); 
		return ApiResult.data(permissions.stream().filter(p -> p.getParentId().equals("0")).collect(Collectors.toList()));
	}

	private void setChildNew(List<PermissionChildVO> permissions) {
		permissions.parallelStream().forEach(per -> {
			List<PermissionChildVO> child = permissions.stream().filter(p -> p.getParentId().equals(per.getPermissionId())).collect(Collectors.toList());
			// 三级权限
			child.parallelStream().forEach(perT -> {
				List<PermissionChildVO> childT = permissions.stream().filter(p -> p.getParentId().equals(perT.getPermissionId())).collect(Collectors.toList());
				perT.setChild(childT);
			});
			per.setChild(child);
		});
	}
	
	/**
	 * 菜单列表
	 * 
	 * @param pId
	 * @param permissionsAll
	 * @param list
	 */
	private void setPermissionsList(String pId, List<Permission> permissionsAll, List<Permission> list) {
		for (Permission per : permissionsAll) {
			if (per.getParentId().equals(pId)) {
				list.add(per);
				if (permissionsAll.stream().filter(p -> p.getParentId().equals(per.getPermissionId())).findAny() != null) {
					setPermissionsList(per.getPermissionId(), permissionsAll, list);
				}
			}
		}
	}

	@GetMapping
	@ApiOperation(value = "权限（菜单）-菜单列表")
	/*//@PreAuthorize("hasAuthority('sys:menu:query') or hasAuthority('sys:role:query')")*/
	public List<Permission> permissionsList() {
		List<Permission> permissionsAll = permissionDao.listAll();

		List<Permission> list = Lists.newArrayList();
		setPermissionsList("0", permissionsAll, list);

		return list;
	}

	@GetMapping("/all")
	@ApiOperation(value = "权限（菜单）-所有菜单")
	//@PreAuthorize("hasAuthority('sys:menu:query') or hasAuthority('sys:role:query')")
	public JSONArray permissionsAll() {
		List<Permission> permissionsAll = permissionDao.listAll();
		JSONArray array = new JSONArray();
		setPermissionsTree("0", permissionsAll, array);

		return array;
	}

	@GetMapping("/parents")
	@ApiOperation(value = "权限（菜单）-一级菜单")
	//@PreAuthorize("hasAuthority('sys:menu:query') or hasAuthority('sys:role:query')")
	public List<Permission> parentMenu() {
		// List<Permission> parents = permissionDao.listParents();
		List<Permission> parents = permissionDao.listParentsNotBtn();
		//List<Permission> parents = permissionDao.listAll();
		return parents;
		/*
		 * final List<Permission> permissions = parents.stream().filter(l ->
		 * l.getType().equals(1)) .collect(Collectors.toList());
		 * 
		 * setChild(permissions);
		 * 
		 * return permissions.stream().filter(p ->
		 * p.getParentId().equals("0")).collect(Collectors.toList());
		 */
	}

	/**
	 * 菜单树
	 * 
	 * @param pId
	 * @param permissionsAll
	 * @param array
	 */
	private void setPermissionsTree(String pId, List<Permission> permissionsAll, JSONArray array) {
		for (Permission per : permissionsAll) {
			if (per.getParentId().equals(pId)) {
				String string = JSONObject.toJSONString(per);
				JSONObject parent = (JSONObject) JSONObject.parse(string);
				array.add(parent);

				if (permissionsAll.stream().filter(p -> p.getParentId().equals(per.getPermissionId())).findAny() != null) {
					JSONArray child = new JSONArray();
					parent.put("child", child);
					setPermissionsTree(per.getPermissionId(), permissionsAll, child);
				}
			}
		}
	}

	@GetMapping(params = "roleId")
	@ApiOperation(value = "权限（菜单）-根据角色id查询权限")
	//@PreAuthorize("hasAnyAuthority('sys:menu:query','sys:role:query')")
	public ApiResult<?> listByRoleId(String roleId) {
		if(StringUtilsV2.isBlank(roleId)){
			return ApiResult.error("要查询的id不能为空");
		}
    	return ApiResult.data(permissionDao.listByRoleId(roleId));
	}
	
	@GetMapping("/{id}")
	@ApiOperation(value = "权限（菜单）-根据菜单id获取菜单")
	//@PreAuthorize("hasAuthority('sys:menu:query')")
	public ApiResult<?> get(@PathVariable String id) {
		if(StringUtilsV2.isBlank(id)){
			return ApiResult.error("要查询的id不能为空");
		}
		Permission permission = permissionDao.getById(id);
		if(permission != null){
			String parentId = permission.getParentId();
			List<String> ids = new ArrayList<String>();
			while (!"0".equals(parentId)) {
				ids.add(parentId);
				Permission permissionW = permissionDao.getById(parentId);
				if(permissionW != null){
					parentId = permissionW.getParentId();
				}
			}
			Collections.reverse(ids);
			permission.setParentIds(ids);
		}
		return ApiResult.data(permission);

	}
	
	@LogAnnotation
	@PostMapping
	@ApiOperation(value = "权限（菜单）-保存菜单")
	//@PreAuthorize("hasAuthority('sys:menu:add')")
	public ApiResult<?> save(HttpServletRequest request,@RequestBody Permission permission) {
		LoginUser loginUser = UserUtil.getLoginUser();
		permission.setCreateUserId(loginUser.getUserId());
		ApiResult<?> apiResult = verifyForm(request,permission);// 校验数据
		if(apiResult != null){
			return apiResult;
		}
		permissionDao.save(permission);
		// 将该权限赋给超级管理员角色
		List<String> permissionIds = new ArrayList<String>();
		permissionIds.add(permission.getPermissionId());
		roleDao.saveRolePermission("1", permissionIds);
		return ApiResult.ok();
	}

	@LogAnnotation
	@PutMapping
	@ApiOperation(value = "权限（菜单）-修改菜单")
	//@PreAuthorize("hasAuthority('sys:menu:edit')")
	public ApiResult<?> update(HttpServletRequest request,@RequestBody Permission permission) {
		ApiResult<?> apiResult = verifyForm(request,permission);// 校验数据
		if(apiResult != null){
			return apiResult;
		}
		if(StringUtilsV2.isBlank(permission.getPermissionId())){
			return ApiResult.error("要修改的菜单ID不能为空");
		}
		LoginUser loginUser = UserUtil.getLoginUser();
		permission.setUpdateUserId(loginUser.getUserId());
		permissionService.update(permission);
		return ApiResult.ok();
	}

	/**
	 * 校验权限
	 * 
	 * @return
	 */
	@GetMapping("/owns")
	@ApiOperation(value = "权限（菜单）-校验当前用户的权限")
	public Set<String> ownsPermission(HttpServletRequest request) {
		Integer sysId = TokenFilter.getSysId(request);
		LoginUser loginUser = UserUtil.getLoginUser();
		if(loginUser.getIsSuperAdminRole()) {
			return permissionDao.listPermissionCodeBySysId(sysId);
		}else {
			return permissionDao.listPermissionCodeByUserIdAndSysId(loginUser.getUserId(),sysId);
		}
	}

	@LogAnnotation
	@DeleteMapping("/{id}")
	@ApiOperation(value = "权限（菜单）-删除菜单")
	//@PreAuthorize("hasAuthority('sys:menu:del')")
	public void delete(@PathVariable String id) {
		permissionService.delete(id);
	}

	/**
	 * 验证参数是否正确
	 */
	private ApiResult<?> verifyForm(HttpServletRequest request,Permission permission) {
		if (StringUtilsV2.isBlank(permission.getPermissionName())) {
			return ApiResult.error("菜单名称不能为空");
		}
		// 当前菜单类型
		Integer type = permission.getType();
		if (type == null) {
			return ApiResult.error("菜单类型不能为空");
		}
		// 上级菜单id
		String parentId = permission.getParentId();
		Integer sysid = TokenFilter.getSysId(request);
		// 没传父菜单id默认为顶级菜单
		if (StringUtilsV2.isBlank(parentId) || "0".equals(parentId)) {
			permission.setParentId("0");
			// 默认为顶级
			permission.setLevel(0);
			permission.setSysId(CommUtil.null2Int(sysid));
		} else {
			Permission parentPermission = permissionDao.getById(parentId);
			Integer parentLevel = parentPermission.getLevel();
			if (parentLevel != null) {
				permission.setLevel(parentLevel + 1);
				permission.setSysId(parentPermission.getSysId());
			}else {
				permission.setLevel(0);
				permission.setSysId(CommUtil.null2Int(sysid));
			}
		}
		return null;
	}
}
